﻿using Globsite.Globalization.Mvc.DbResources.Repositories;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Resources;

namespace Globsite.Globalization.Mvc.DbResources
{
    public class DbResourceWriter : IResourceWriter
    {
        private readonly string baseName;
        private readonly CultureInfo cultureInfo;
        private IDictionary<string, string> resources;

        private RepositoryBase resourceRepositoryField;
        private RepositoryBase resourceRepository
        {
            get { return this.resourceRepositoryField ?? (this.resourceRepositoryField = (new RepositoryFactory()).CreateRepository()); }
        }

        #region Ctors

        public DbResourceWriter(string baseName, CultureInfo cultureInfo)
        {
            Debug.WriteLine(string.Format("DbResourceWriter.DbResourceWriter({0}, {1})", baseName, cultureInfo));

            this.baseName = baseName;
            this.cultureInfo = cultureInfo;
            this.resources = new Dictionary<string, string>();
        }

        public DbResourceWriter(IResourceReader resourceReader, string baseName, CultureInfo cultureInfo)
            : this(baseName, cultureInfo)
        {
            Debug.WriteLine(string.Format("DbResourceWriter.DbResourceWriter({0}, {1}, {2})", resourceReader, baseName, cultureInfo));

            // Dodaj do słownika klucze przesłanego obiektu.
            foreach (DictionaryEntry resource in resourceReader)
                this.resources.Add((string)resource.Key, (string)resource.Value);
        }

        #endregion

        #region IResourceWriter Members

        // Adds a named resource of type String to the list of resources to be written.
        public void AddResource(string name, string value)
        {
            Debug.WriteLine(string.Format("DbResourceWriter.AddResource({0}, {1})", name, value));

            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            this.resources.Add(name, value);
        }

        // Adds a named resource of type Object to the list of resources to be written.
        public void AddResource(string name, object value)
        {
            Debug.WriteLine(string.Format("DbResourceWriter.AddResource({0}, {1})", name, value));

            throw new UnsupportedResourceType("Resource values other than strings are not supported.");
        }

        // Adds an 8-bit unsigned integer array as a named resource to the list of resources to be written.
        public void AddResource(string name, byte[] value)
        {
            Debug.WriteLine(string.Format("DbResourceWriter.AddResource({0}, {1})", name, value));

            throw new UnsupportedResourceType("Resource values other than strings are not supported.");
        }

        // Closes the underlying resource file or stream, ensuring all the data has been written to the file.
        public void Close()
        {
            Debug.WriteLine("DbResourceWriter.Close()");

            Generate();
            Dispose();
        }

        // Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. (Inherited from IDisposable.)
        public void Dispose()
        {
            Debug.WriteLine("DbResourceWriter.Dispose()");

            this.resources = null;
        }

        // Writes all the resources added by the AddResource method to the output file or stream.
        public void Generate()
        {
            Debug.WriteLine("DbResourceWriter.Generate()");

            this.resourceRepository.SynchronizeResources(this.resources, this.baseName, this.cultureInfo.Name);
        }

        #endregion
    }
}
